package scatter.wxminiapp.rest.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import me.chanjar.weixin.common.session.WxSessionManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import scatter.common.dict.PublicDictEnums;
import scatter.common.rest.validation.DictService;
import scatter.wxminiapp.pojo.po.WxMaMsgReply;
import scatter.wxminiapp.rest.basic.config.WxMaProperties;
import scatter.wxminiapp.rest.mapper.WxMaMsgReplyMapper;
import scatter.wxminiapp.rest.service.IWxMaMsgReplyService;
import scatter.common.rest.service.IBaseAddUpdateQueryFormServiceImpl;
import org.springframework.stereotype.Service;
import scatter.wxminiapp.pojo.form.WxMaMsgReplyAddForm;
import scatter.wxminiapp.pojo.form.WxMaMsgReplyUpdateForm;
import scatter.wxminiapp.pojo.form.WxMaMsgReplyPageQueryForm;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <p>
 * 小程序消息回复表 服务实现类
 * </p>
 *
 * @author yw
 * @since 2021-11-23
 */
@Service
@Transactional
public class WxMaMsgReplyServiceImpl extends IBaseAddUpdateQueryFormServiceImpl<WxMaMsgReplyMapper, WxMaMsgReply, WxMaMsgReplyAddForm, WxMaMsgReplyUpdateForm, WxMaMsgReplyPageQueryForm> implements IWxMaMsgReplyService {

    @Autowired
    private DictService dictService;

    @Autowired
    private WxMaProperties maProperties;

    @Override
    public void preAdd(WxMaMsgReplyAddForm addForm,WxMaMsgReply po) {
        if (!isStrEmpty(po.getAppCode())) {
            po.setAppName(maProperties.abtainAppNameByAppCodeOrAppId(po.getAppCode()));
        }
        super.preAdd(addForm,po);

    }

    @Override
    public void preUpdate(WxMaMsgReplyUpdateForm updateForm,WxMaMsgReply po) {
        if (!isStrEmpty(po.getAppCode())) {
            po.setAppName(maProperties.abtainAppNameByAppCodeOrAppId(po.getAppCode()));
        }
        super.preUpdate(updateForm,po);

    }


    @Override
    public WxMaMsgReply getMatched(WxMaMessage wxMessage, Map<String, Object> context, WxMaService wxMaService, WxSessionManager sessionManager) {
        String appId = WxMaConfigHolder.get();
        Assert.hasText(appId,"appId未获取到，这可能是一个bug");
        WxMaProperties.MaConfig mpConfig = maProperties.abtainConfigByAppCodeOrAppId(appId);
        Assert.notNull(mpConfig,"未获取到小程序配置，请检查配置");
        Assert.hasText(mpConfig.getAppCode(),"appCode必须配置，appCode用来唯一标识一个小程序配置");
        WxMaMsgReply mpMsgReplyQuery = new WxMaMsgReply();
        mpMsgReplyQuery.setAppCode(mpConfig.getAppCode());
        QueryWrapper<WxMaMsgReply> queryWrapper = Wrappers.query(mpMsgReplyQuery).and(mpMsgReplyQueryWrapper -> {
            mpMsgReplyQueryWrapper.lambda().isNull(WxMaMsgReply::getMatchFromUser);
        });
        // 接收人
        if(isStrEmpty(wxMessage.getFromUser())){
            queryWrapper.lambda().isNull(WxMaMsgReply::getMatchFromUser);
        }else {
            queryWrapper.and(qw-> {
                qw.lambda().isNull(WxMaMsgReply::getMatchFromUser).or().eq(WxMaMsgReply::getMatchFromUser, wxMessage.getFromUser());
            });
        }
        // xml消息类型
        if(isStrEmpty(wxMessage.getMsgType())){
            queryWrapper.lambda().isNull(WxMaMsgReply::getMatchMsgTypeDictId);
        }else {
            String msgType = WxMaMsgReply.WX_MA_PUSH_XML_MSG_TYPE + wxMessage.getMsgType();
            String dictId = dictService.getIdByGroupCodeAndValue(WxMaMsgReply.XmlMsgTypeDictGroup.wx_ma_push_xml_msg_type.groupCode(),msgType.toLowerCase());
            // 没有字典，直接返回空
            if (dictId == null) {
                return null;
            }
            queryWrapper.and(qw-> {
                qw.lambda().isNull(WxMaMsgReply::getMatchMsgTypeDictId).or().eq(WxMaMsgReply::getMatchMsgTypeDictId, dictId);
            });
        }
        // 事件类型
        if(isStrEmpty(wxMessage.getEvent())){
            queryWrapper.lambda().isNull(WxMaMsgReply::getMatchEventTypeDictId);
        }else {
            String msgType = WxMaMsgReply.EVENT_TYPE_DICT_ITEM_PREFIX + wxMessage.getEvent();
            String dictId = dictService.getIdByGroupCodeAndValue(WxMaMsgReply.EventTypeDictGroup.wx_ma_push_event_type.groupCode(),msgType.toLowerCase());
            // 没有字典，直接返回空
            if (dictId == null) {
                return null;
            }
            queryWrapper.lambda().eq(WxMaMsgReply::getMatchEventTypeDictId, dictId);
        }
        // 按权重优先级和更新时间倒序排序
        queryWrapper.lambda().orderByDesc(WxMaMsgReply::getPriority).orderByDesc(WxMaMsgReply::getUpdateAt);

        List<WxMaMsgReply> list = list(queryWrapper);

        for (WxMaMsgReply mpMsgReply : list) {
            if(test(wxMessage,mpMsgReply)){
                return mpMsgReply;
            }
        }
        return null;
    }

    /**
     * 判断是否匹配
     * @param wxMessage
     * @param mpMsgReply
     * @return
     */
    protected boolean test(WxMaMessage wxMessage,WxMaMsgReply mpMsgReply) {
        return
                (mpMsgReply.getMatchFromUser() == null || mpMsgReply.getMatchFromUser().equals(wxMessage.getFromUser()))
                        &&
                        (mpMsgReply.getMatchMsgTypeDictId() == null || (WxMaMsgReply.WX_MA_PUSH_XML_MSG_TYPE +wxMessage.getMsgType()).equalsIgnoreCase(dictService.getValueById(mpMsgReply.getMatchMsgTypeDictId())))
                        &&
                        (mpMsgReply.getMatchEventTypeDictId() == null || (WxMaMsgReply.EVENT_TYPE_DICT_ITEM_PREFIX +wxMessage.getEvent()).equalsIgnoreCase(dictService.getValueById(mpMsgReply.getMatchEventTypeDictId())))
                       // &&
                        //(mpMsgReply.getMatchEventKey() == null || matchType(mpMsgReply.getMatchEventKeyMatchDictId(),mpMsgReply.getMatchEventKey(),wxMessage.getEventKey()))
                        &&
                        (mpMsgReply.getMatchContent() == null || matchType(mpMsgReply.getMatchContentMatchDictId(),mpMsgReply.getMatchContent(), StringUtils.trimToNull(wxMessage.getContent())))

                ;
    }

    /**
     * 根据匹配方式匹配
     * @param matchTypeDictId
     * @param matchRuleValue
     * @param originValue
     * @return
     */
    private boolean matchType(String matchTypeDictId,String matchRuleValue,String originValue){
        String dictValue = dictService.getValueById(matchTypeDictId);
        // 相等
        if (PublicDictEnums.DictMatchType.match_eq.itemValue().equals(dictValue)) {
            return matchRuleValue.equalsIgnoreCase(originValue);
        }
        // 模糊
        if (PublicDictEnums.DictMatchType.match_like.itemValue().equals(dictValue)) {
            if (originValue != null) {
                return originValue.contains(matchRuleValue);
            }
        }
        // 左模糊匹配
        if (PublicDictEnums.DictMatchType.match_like_left.itemValue().equals(dictValue)) {
            if (originValue != null) {
                return originValue.startsWith(matchRuleValue);
            }
        }
        // 右模糊匹配
        if (PublicDictEnums.DictMatchType.match_like_right.itemValue().equals(dictValue)) {
            if (originValue != null) {
                return originValue.endsWith(matchRuleValue);
            }
        }
        // 正则匹配
        if (PublicDictEnums.DictMatchType.match_regex.itemValue().equals(dictValue)) {
            return Pattern.matches(matchRuleValue, StringUtils.trimToEmpty(originValue));
        }
        return false;
    }
}
